/*
 * Simple test file for cxxomfort's 
 * system_error  feature backports.
 * 
 * This example draws from the example posted in 
 * https://en.cppreference.com/w/cpp/error/generic_category
 *
 */

#include <cxxomfort/base.hpp>
#include <cxxomfort/library/system_error.hpp>
#include <cxxomfort/system_error.hpp>
#include <cxxomfort/string_view.hpp>
#include <cxxomfort/ostream.hpp>
#include <iostream>
#include <cerrno>
#include <string>
#include <fstream>
#include <cxxomfort/library/type_name.hpp>

namespace cxxomfort {

#if 1
CXXO_OPEN_ENUM_OR_ENUMCLASS(main_errors,int) 
#else
CXXO_OPEN_TYPESAFE_ENUM(main_errors,int) 
#endif
{
	main_1, main_2, main_3
} 
#if 0
CXXO_CLOSE_TYPESAFE_ENUM(main_errors,int);
#else
CXXO_CLOSE_ENUM_OR_ENUMCLASS(main_errors,int);
#endif

}

namespace std {
	template<> struct is_error_code_enum< ::cxxomfort::main_errors> 
	: std::true_type {};
}

namespace cxxomfort {

struct foo_category_t : std::error_category {
	char const* name () const CXXO_NOEXCEPTNOTHROW { return "foo_category"; }
	std::string message (int e) const { 
		return std::string("Foo_") + std::to_string(e); 
	}
};

static inline 
std::error_category const& foo_category () CXXO_NOEXCEPT {
	static foo_category_t g;
	return g;
}

inline 
std::error_code make_error_code (main_errors const e) CXXO_NOEXCEPT {
	return std::error_code(explicit_cast<int>(e), foo_category());
}

#if (CXXOMFORT_CXX_STD<2011)
inline 
std::error_code make_error_code (main_errors::type const e) CXXO_NOEXCEPT {
	main_errors m(e);
	return std::error_code(e, foo_category());
}
#endif

}

namespace cxl= cxxomfort::library;

int main() {

    using namespace std;
    using cxxomfort::library::type_name;

    cxxomfort::output_info();
    cout<< endl;
    cout<< "error code foo is: "<< type_name<cxxomfort::main_errors>()<< endl;
    cout<< "foo's category is: "<< type_name<cxxomfort::foo_category_t>()<< endl;
    error_category const& foo_cat = cxxomfort::foo_category();
    cout<< "Category is: "<< foo_cat.name()<< endl;
    cout<< "Making an error code: \n";
    error_code efoo = make_error_code(cxxomfort::main_errors::main_1);
    cout<< efoo<< ", "<< efoo.message()<< endl;
    cout<< "\n\n";
    
    cout<< "error code misc is: "<< type_name<cxxomfort::misc_errors>()<< endl;
    cout<< "misc's category is: "<< type_name<cxxomfort::library::misc_errors_category_t>()<< endl;
    error_category const& misc_cat = cxl::misc_error_category();
    cout<< "Category is: "<< misc_cat.name()<< endl;
    
    cout<< "Making an error_code: \n";
    error_code ec = make_error_code(cxxomfort::misc_errors::unknown);
    cout<< ec<< ", "<< ec.message()<< endl;
    ec = make_error_code(cxxomfort::misc_errors::copy_constructor_failure);
    cout<< ec<< ", "<< ec.message()<< endl;
    ec= make_error_code(cxxomfort::fix::errc::value_too_large);
    cout<< ec<< ", "<< ec.message()<< endl;

}
